<?php
declare(strict_types=1);

namespace app\middleware;

use app\model\Admin;
use think\facade\Log;
use Firebase\JWT\{JWT, Key};
use think\facade\Config;

class AdminAuthMiddleware extends BaseAuth
{
    // 白名单
    protected $whitelist = [
        '/admin/login',
        '/admin/logout'
    ];

    public function handle($request, \Closure $next)
    {
        // 检查是否在白名单中
        $path = $request->pathinfo();
        if (in_array('/' . $path, $this->whitelist)) {
            return $next($request);
        }

        try {
            // 添加调试日志
            Log::debug('Current path: ' . $path);
            Log::debug('Request headers: ' . json_encode($request->header()));
            
            // 获取token
            $token = $request->header('Authorization');
            if (empty($token)) {
                Log::warning('No Authorization header found');
                return json(['code' => 401, 'msg' => '请先登录']);
            }

            // 去掉可能存在的Bearer 前缀
            $token = str_replace('Bearer ', '', $token);
            
            // 添加调试日志
            Log::debug('Processing token: ' . $token);
            
            // 解析token
            $key = Config::get('jwt.key');
            $decoded = JWT::decode($token, new Key($key, 'HS256'));
            
            // 验证token类型
            if (!isset($decoded->type) || $decoded->type !== 'admin') {
                return json(['code' => 401, 'msg' => '无效的token类型']);
            }
            
            // 验证管理员是否存在
            $admin = Admin::find($decoded->id);
            if (!$admin) {
                return json(['code' => 401, 'msg' => '管理员不存在']);
            }
            
            // 验证管理员状态
            if ($admin->status != 1) {
                return json(['code' => 401, 'msg' => '账号已被禁用']);
            }
            
            // 将管理员ID保存到request中
            $request->adminId = $decoded->id;
            
            // 将decoded对象转为数组
            $tokenInfo = json_decode(json_encode($decoded), true);
            
            // 生成新token
            $newToken = $this->refreshToken($tokenInfo);
            
            // 执行后续中间件或控制器方法
            $response = $next($request);
            
            // 在响应头中返回新token
            if ($newToken) {
                $response->header(['Authorization' => $newToken]);
            }
            
            return $response;
            
        } catch (\Firebase\JWT\ExpiredException $e) {
            Log::warning('Token expired: ' . $e->getMessage());
            return json(['code' => 401, 'msg' => '登录已过期，请重新登录']);
        } catch (\Exception $e) {
            Log::error('JWT验证失败: ' . $e->getMessage());
            return json(['code' => 401, 'msg' => '认证失败']);
        }
    }

    /**
     * 刷新token
     */
    protected function refreshToken(array $tokenInfo): string
    {
        // 如果token还有不到一半的有效期，则刷新
        $expire = Config::get('jwt.expire', 7200);
        $halfTime = $expire / 2;
        
        if (time() - $tokenInfo['iat'] < $halfTime) {
            return '';
        }
        
        $payload = [
            'iss' => 'wasass',
            'aud' => 'admin',
            'iat' => time(),
            'exp' => time() + $expire,
            'id' => $tokenInfo['id'],
            'type' => 'admin'
        ];
        
        return JWT::encode($payload, Config::get('jwt.key'), 'HS256');
    }

    /**
     * 获取守卫名称
     */
    protected function getGuard(): string
    {
        return 'admin';
    }
} 